/**
 * 
 */
package ikelib;

/**
 * @author Toshiharu Ikeda <ikeda.104@gmail.com>
 *
 */
abstract class Integration {
	
	protected double TimeStep = 1;	

	protected class Statistics{
		public double Max;
		public double Min;
		public double Mean;
		public int Length;
		public Statistics(){
			Max=Double.MIN_VALUE;
			Min=Double.MAX_VALUE;
			Mean = 0.0;
			Length = 0;
		}
	};
	

	public Integration(double timestep){
		TimeStep = timestep;
	}
	/**
	 * 
	 * @param acs
	 * @return
	 */
	abstract boolean Calc(double[] acs);
	abstract boolean Calc(double[] acs,double ofs);
	/**
	 * 最大値、最小値、平均値、データ長を計算して返す
	 * @param d doube[] 計算対象のデータ
	 * @return　Statisticsを返す
	 */
	protected Statistics CalcStatistics(double[] d){
		Statistics ret = new Statistics();
		ret.Length = d.length;
		for(int i=0;i<ret.Length;i++){
			if(ret.Max < d[i] ) ret.Max = d[i];
			if(ret.Min > d[i] ) ret.Min = d[i];
			ret.Mean += d[i];
		}
		ret.Mean /= ret.Length;
		return ret;
	}
	/**
	 * データをオフセットしたものを返す。ret[i] = d[i] + ofs
	 * @param d
	 * @param ofs
	 */
	protected double[] Offset(double[] d,double ofs){
		double[] ret = new double[d.length];
		for(int i=0;i<d.length;i++){
			ret[i] = d[i] + ofs;
		}
		return ret;
	}
	/**
	 * データの振幅を変更する。　ret[i] = d[i] * amp
	 * @param d 
	 * @param amp
	 * @return
	 */
	protected double[] Amp(double[] d,double amp){
		double[] ret = new double[d.length];
		for(int i=0;i<d.length;i++){
			ret[i] = d[i]*amp;
		}
		return ret;
	}
	/**
	 * 台形則による積分を行う
	 * @param d
	 * @return
	 */
	protected double TrapezoidalIntegration(double [] d,double step){
		double ret=0;
		int max = d.length;
		for(int i=1;i<max;i++){
			ret += (d[i-1]+d[i])/2*step;
		}
		return ret;
	}
}
